# -*- coding: utf-8 -*-

"""
os.link and os.symlink for windows

Note: CreateSymbolicLink works only on Vista with Python =>v2.6!
See: https://sourceforge.net/tracker/index.php?func=detail&aid=2489735&group_id=78018&atid=551954


Read/Write file properties using IPropertySetStorage:
http://www.google.de/codesearch/p?hl=de#uAEYIURQYQw/minds/weblib/win32/ntfs_util.py&q=NTFS%20lang:python

"""

import os
import sys
import subprocess


# path to sysinternals "junction.exe":
# http://technet.microsoft.com/en-us/sysinternals/bb896768.aspx
JUNCTION_EXE = "junction.exe" 


IS_WIN = sys.platform == "win32"

if IS_WIN:
    import win32file


def nlinks(pathname):
    """Return number of hardlinks for the given file."""
    fh = win32file.CreateFile(pathname,
        win32file.GENERIC_READ, win32file.FILE_SHARE_READ,
        None, win32file.OPEN_EXISTING, 0, None)
    res = win32file.GetFileInformationByHandle(fh)
    fh.Close()
    return res[7]



# TODO:
def win32_readlink(path):
    pass
def win32_unlink(path):
    pass
def win32_islink(path):
    pass



def win32_os_link(src, dst):
    """
    NTFS 3.X can create hardlinks for files
    http://en.wikipedia.org/wiki/NTFS#Hard_links

    from http://en.wikipedia.org/wiki/Hard_link :
    ---
    The Windows API from Windows 2000 onwards includes a CreateHardLink() call
    to create hard links, DeleteFile() is used to remove them, and
    GetFileInformationByHandle() can be used to determine the number of hard
    links associated with a file. Hard links require a NTFS partition.
    ---
    
    IMPORTANT:
        * The win32api used reverse arguments: dst, src !!!
    """
    win32file.CreateHardLink(dst, src, SecurityAttributes=None)


def win32_os_symlink(src, dst):
    """
    Normaly i would like to use win32file.CreateSymbolicLink, but this doesn't
    work. Some rights are needed but absent.
    Work-a-round: using sysinternals "junction.exe"
    
    Note: returns the output
    """   
    cmd = [JUNCTION_EXE, dst, src] # reverse arguments: dst, src
    #print " ".join(cmd)
    
    process = subprocess.Popen(
        cmd, shell=True,
        stdout=subprocess.PIPE, 
        stderr=subprocess.PIPE, 
    )
    process.wait()
    
    output = process.stdout.read().strip()
    stderr = process.stderr.read().strip()
    returncode = process.returncode
    if returncode!=0 or stderr:
        raise OSError(
            "Can't symlink (returncode: %r): %r" % (returncode, stderr)
        )
        
    return output



#~ http://paste.pocoo.org/show/85401/










if IS_WIN:
    os.link = win32_os_link
    os.symlink = win32_os_symlink


if __name__ == '__main__':
    if IS_WIN:
        from win32com.shell import shell
        print "shell.IsUserAnAdmin:", shell.IsUserAnAdmin()
    
    os.chdir("..")
    
    #--------------------------------------------------------------------------
    # simple symlink test 

    src = "example\\project A"
    dst = "output path\\test1"
    
    assert os.path.isdir(src)
    assert not os.path.exists(dst)
    
    os.symlink(src, dst)
    
    assert os.path.isdir(dst)
    os.rmdir(dst)
    assert os.path.isdir(src)
    assert not os.path.exists(dst)
    
    #--------------------------------------------------------------------------
    # simple link test

    src = "example\\project A\\example_picture1.jpg"
    dst = "output path\\example_picture1.jpg"
    
    assert os.path.isfile(src)
    assert not os.path.exists(dst)
    
    os.link(src, dst)
    
    assert os.path.isfile(dst)
    os.remove(dst)
    assert not os.path.exists(dst)
    assert os.path.isfile(src)
